#include "cutil.h"

/**
    @file cutil.cpp
    @author Claus Wimmer
    @date 2014-01-04

    Project: secondspace
    Licence: LGPL (Lesser GPL)
*/

using namespace std;

QString CUtil::configdir = QDir::homePath() + "/secondspace/";

const QString CUtil::includepath = QString("-I %1").arg(CUtil::configdir);

QString CUtil::version = "NULL";

QString CUtil::outputdir;

QString CUtil::tmpdir;

const QString CUtil::includekernelfile = "kern_include.cl";

const QString CUtil::initkernelfile = "kern_init.cl";

const QString CUtil::stepkernelfile = "kern_step.cl";

QString CUtil::scenetitle = "Built in constants";

int CUtil::x = 50;

int CUtil::y = 50;

int CUtil::width = 400;

int CUtil::height = 400;

int CUtil::dt = 10;

int CUtil::stepcount = 1000;

int CUtil::pixwidth = 100;

int CUtil::pixheight = 100;

int CUtil::maxslider = 100;

int CUtil::minslider = 0;

int CUtil::valslider = 1;

int CUtil::layers = 1;

int CUtil::varsiz = 8;

int CUtil::zoom = 2;

int CUtil::numsteps = 4;

int CUtil::modus = CUtil::MODUS_0;

// Show as output stream.
void CUtil::showMessage(QString msg) {
    cout << "seconspace : " << msg.toStdString() << endl;
}

// Copy only if destination does not exist.
void CUtil::copyFile(QString srcpath, QString dstpath) {
    if(QFile(dstpath).exists()){
        return;
    }
    QFile src(srcpath), dst(dstpath);
    if(!src.open(QFile::ReadOnly)){
        showMessage(QString("Cannot open file %1.").arg(srcpath));
        exit(-1);
    }
    if(!dst.open(QFile::WriteOnly)){
        showMessage(QString("Cannot open file %1").arg(dstpath));
        exit(-1);
    }
    QByteArray b = src.readAll();
    dst.write(b);
    src.close();
    dst.close();
}

// Copy only if destination does not exist.
void CUtil::mkpath(QString dirpath) {
    if(QDir(dirpath).exists()){
        return;
    }
    if(!QDir::root().mkpath(dirpath)){
        showMessage(QString("Creation of directory %1 failed.").arg(dirpath));
        exit(-1);
    }
}

void CUtil::provideConfigDir() {

    CUtil::mkpath(CUtil::configdir);
    CUtil::copyFile(":/secondspace.cfg", QString("%1/secondspace.cfg").arg(CUtil::configdir));

    QFile cfg(QString("%1/secondspace.cfg").arg(CUtil::configdir));
    cfg.open(QFile::ReadOnly);
    while(!cfg.atEnd()){
        QString line = QString(cfg.readLine().data()).trimmed();
        if(!line.startsWith('#')){
            QStringList var = line.split('=');
            if(var[0] == "version"){
                CUtil::version = var[1];
                CUtil::showMessage(QString("Version = %1.").arg(CUtil::version));
            }
            if(var[0] == "outputdir"){
                CUtil::outputdir = var[1];
                CUtil::showMessage(QString("Outputdir = %1.").arg(CUtil::outputdir));
            }
            if(var[0] == "tmpdir"){
                CUtil::tmpdir = var[1];
                CUtil::showMessage(QString("Tmpdir = %1.").arg(CUtil::tmpdir));
            }
            if(var[0] == "scenetitle"){
                CUtil::scenetitle = var[1];
                CUtil::showMessage(QString("Scenetitle = %1.").arg(CUtil::scenetitle));
            }
            if(var[0] == "x"){
                CUtil::x = var[1].toInt();
                CUtil::showMessage(QString("X = %1.").arg(CUtil::x));
            }
            if(var[0] == "y"){
                CUtil::y = var[1].toInt();
                CUtil::showMessage(QString("Y = %1.").arg(CUtil::y));
            }
            if(var[0] == "width"){
                CUtil::width = var[1].toInt();
                CUtil::showMessage(QString("Width = %1.").arg(CUtil::width));
            }
            if(var[0] == "height"){
                CUtil::height = var[1].toInt();
                CUtil::showMessage(QString("Height = %1.").arg(CUtil::height));
            }
            if(var[0] == "dt"){
                CUtil::dt = var[1].toInt();
                CUtil::showMessage(QString("Dt = %1.").arg(CUtil::dt));
            }
            if(var[0] == "stepcount"){
                CUtil::stepcount = var[1].toInt();
                CUtil::showMessage(QString("Stepcount = %1.").arg(CUtil::stepcount));
            }
            if(var[0] == "pixwidth"){
                CUtil::pixwidth = var[1].toInt();
                CUtil::showMessage(QString("Pixwidth = %1.").arg(CUtil::pixwidth));
            }
            if(var[0] == "pixheight"){
                CUtil::pixheight = var[1].toInt();
                CUtil::showMessage(QString("Pixheight = %1.").arg(CUtil::pixheight));
            }
            if(var[0] == "maxslider"){
                CUtil::maxslider = var[1].toInt();
                CUtil::showMessage(QString("Maxslider = %1.").arg(CUtil::maxslider));
            }
            if(var[0] == "minslider"){
                CUtil::minslider = var[1].toInt();
                CUtil::showMessage(QString("Minslider = %1.").arg(CUtil::minslider));
            }
            if(var[0] == "valslider"){
                CUtil::valslider = var[1].toInt();
                CUtil::showMessage(QString("Valslider = %1.").arg(CUtil::valslider));
            }
            if(var[0] == "layers"){
                CUtil::layers = var[1].toInt();
                CUtil::showMessage(QString("Layers = %1.").arg(CUtil::layers));
            }
            if(var[0] == "varsiz"){
                CUtil::varsiz = var[1].toInt();
                CUtil::showMessage(QString("Varsiz = %1.").arg(CUtil::varsiz));
            }
            if(var[0] == "zoom"){
                CUtil::zoom = var[1].toInt();
                CUtil::showMessage(QString("Zoom = %1.").arg(CUtil::zoom));
            }
            if(var[0] == "numsteps"){
                CUtil::numsteps = var[1].toInt();
                CUtil::showMessage(QString("Numsteps = %1.").arg(CUtil::numsteps));
            }
            if(var[0] == "modus"){
                CUtil::modus = var[1].toInt();
                CUtil::showMessage(QString("Modus = %1.").arg(CUtil::modus));
            }
        }
    }
    if(0 < CUtil::outputdir.length()){
        CUtil::mkpath(QString("%1/%2").arg(CUtil::configdir).arg(CUtil::outputdir));
    }
    CUtil::mkpath(QString("%1/%2").arg(CUtil::configdir).arg(CUtil::tmpdir));
    CUtil::copyFile(":/kern_include.cl" , QString("%1/%2").arg(CUtil::configdir).arg(CUtil::includekernelfile));
    CUtil::copyFile(":/kern_init.cl"    , QString("%1/%2").arg(CUtil::configdir).arg(CUtil::initkernelfile));
    CUtil::copyFile(":/kern_step.cl"    , QString("%1/%2").arg(CUtil::configdir).arg(CUtil::stepkernelfile));
}

char *CUtil::fileBytes(QString filepath, size_t *len) {
    QFile file(filepath);
    file.open(QFile::ReadOnly);
    *len = file.bytesAvailable();
    char *buf = new char[*len];
    assert(0 <= file.read(buf, *len));
    file.close();
    return buf;
}

void CUtil::saveImageFile(QImage *image, uint fileindex) {
    if(0 == CUtil::outputdir.length()){
        return;
    }
    // Prepend leading zeros. Fill with zeros.
    QString fname = QString("%1").arg(fileindex);
    while(fname.length() < IMGFILEIDX){
        fname = QString('0') + fname;
    }
    image->save(CUtil::configdir + "/" + CUtil::outputdir + "/" + CUtil::scenetitle + "_" + fname + ".png", IMGFORMAT);
}

void CUtil::clearImageDirectory() {
    QDir outputdir(CUtil::configdir + "/" + CUtil::outputdir);
    // Not root.
    if(1 < outputdir.count()){
        QFileInfoList entries = outputdir.entryInfoList();
        foreach(QFileInfo entry, entries){
            QString path = entry.canonicalFilePath();
            QFile file(path);
            if(file.exists() && path.endsWith(".png")){
                file.remove();
            }
        }
    }
}

QString CUtil::qss() {
    size_t len;
    char *buf = CUtil::fileBytes(STYLESHEETFILE, &len);
    QByteArray bytes(buf, len);
    delete[] buf;
    return QString(bytes);
}
